from rest_framework import serializers

from sysreptor.pentests.models import (
    UploadedAsset,
    UploadedImage,
    UploadedProjectFile,
    UploadedTemplateImage,
    UploadedUserNotebookFile,
    UploadedUserNotebookImage,
)
from sysreptor.utils.files import compress_image


class UploadedFileSerilaizerBase(serializers.ModelSerializer):
    compress_images = True

    resource_type = serializers.SerializerMethodField()

    class Meta:
        fields = ['id', 'created', 'updated', 'resource_type', 'name', 'file']
        extra_kwargs = {
            'file': {'write_only': True},
            'name': {'required': False},
        }

    def get_resource_type(self, obj) -> str:
        return None

    def get_linked_object(self):
        return None

    def create(self, validated_data):
        if self.compress_images:
            validated_data['file'], validated_data['name'] = compress_image(validated_data['file'], validated_data.get('name'))
        validated_data['linked_object'] = self.get_linked_object()
        return super().create(validated_data)


class UploadedImageSerializer(UploadedFileSerilaizerBase):
    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedImage

    def get_linked_object(self):
        return self.context['project']

    def get_resource_type(self, obj) -> str:
        return 'image'


class UploadedUserNotebookImageSerializer(UploadedFileSerilaizerBase):
    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedUserNotebookImage

    def get_linked_object(self):
        return self.context['user']

    def get_resource_type(self, obj) -> str:
        return 'image'


class UploadedTemplateImageSerializer(UploadedFileSerilaizerBase):
    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedTemplateImage

    def get_linked_object(self):
        return self.context['template']

    def get_resource_type(self, obj) -> str:
        return 'image'


class UploadedAssetSerializer(UploadedFileSerilaizerBase):
    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedAsset

    def get_linked_object(self):
        return self.context['project_type']

    def get_resource_type(self, obj) -> str:
        return 'asset'


class UploadedUserNotebookFileSerilaizer(UploadedFileSerilaizerBase):
    compress_images = False

    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedUserNotebookFile

    def get_linked_object(self):
        return self.context['user']

    def get_resource_type(self, obj) -> str:
        return 'file'


class UploadedProjectFileSerilaizer(UploadedFileSerilaizerBase):
    compress_images = False

    class Meta(UploadedFileSerilaizerBase.Meta):
        model = UploadedProjectFile

    def get_linked_object(self):
        return self.context['project']

    def get_resource_type(self, obj) -> str:
        return 'file'

